//字符串（认识String类）：

public class Test {
    public static void main1(String[] args) {
        String str = "Hello";//扎起Java中没有以"\0"结尾这样的说法
        System.out.println(str);

        String str2 = new String("world");//也可以这样写
        //因为String也是引用类型，可以在堆上创造了一定的空间，从而存进对象的值
        System.out.println(str2);

        char[] array = {'a','b','c'};//字符数组
        String str3 = new String(array);//把字符数组变成了字符串
        System.out.println(str3);
        //这种打印会因是调用了toString()的方法
        //当然这个toString是String类中的方法，不是object类中的toString()的方法
        //String本身为字符串，toString直接接受，并返回了内容，所以便也直接打印了
        /*String类的底层方法，String储存在堆的空间中*/

        /*
        String类的两个属性：

        private final char value[];
        private int hash;
        我们需要用字符数组来接收他们的值，拿来的是引用
        hash是内存的分布
         */

        System.out.println(str.length());//调用的是length方法，
        //在数组中，我们可以调用的是length ，而不是length()方法
        int[] arrays = new int[20];
        System.out.println(arrays.length);//length

        System.out.println("=========");
        String string = "";
        System.out.println(string.isEmpty());//判断字符串是否为空

        String string2 = null;
        System.out.println(string2);
        //两者的情况是不一样，但是isEmpty()是判断字符串的内容是否为空，
        //但是这个直接赋值null是代表这个引用，不会堆中的指向了任何对象。

        /*System.out.println(string2.isEmpty());
        //如果把字符串直接赋值为null，再去调用isEmpty,会发生空指针异常（NullPointerException）*/

        System.out.println("==========");

        //当然我们也可以直接去进行用字符串来判断长度
        System.out.println(str.length());
        System.out.println("Hello".length());
        //所以，在Java中“ ”引起来的也是String类型对象。
        System.out.println("==========");
    }

    public static void main(String[] args) {
        //通过了对象的引用，用new来进行
        String str1 = new String("abcde");
        String str2 = new String("abcde");
        System.out.println(str1 == str2);
        //两者没有引用了同一个对象，对象的空间位置不一样所以地址也就不同
        //==比较是否引用同一个对象

        System.out.println(str1.equals(str2));//用equals方法来判断两者的内容是否一样

        String str3 = "abcde";
        String str4 = "abcde";
        System.out.println(str3 == str4);
        //这个是字符串的常量池，我们后期学完哈希表，再去详细去讲解这个常量池

        //简单解释：
        //堆中有一个常量池，我们直接用的字符串，所以我们直接把这个字符串的值整体都放入堆中的常量池，
        //然后先把str3所用的字符串放入其中，然后把str4的字符串放到常量池其中查找，如果常量池已经有了这个字符串，就不会放入其中，并且直接指向了str3的字符串

        /*
        存储用双引号，引起来的字符串，存的是字符串的常量值
        所以也就是以下3点：
        1.看常量池是否存在当前字符串
        2.没有， 则存进去
        3.如果有，那么直接获取这个字符串在常量池当中的地址
         */
        //常量池可以提高储存效率

        /**
         * 在任何情况下，只要等号两边是 引用类型 一定注意 看此时比较的是什么？
         * 如果要比较两个引用 所指向的对象的内容是否一致
         * 一定要重写equals方法，去比较要比较的内容
         * 否则会调用object类中的equals方法，当然返回的也是地址
         *
         * 我们建议自定义类型，一定要重写hashcode和equals方法
         */
    }
}
